package cn.tedu.luban.demand.main.service;

import cn.tedu.luban.demand.main.repository.DemandRepository;
import cn.tedu.luban.demand.protocol.bo.RequestOrderBO;
import cn.tedu.luban.demand.protocol.query.RequestOrderQuery;
import com.tedu.inn.protocol.ListRecordTotalBO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class RequestOrderService {
    @Autowired
    private DemandRepository demandRepository;
    public ListRecordTotalBO<RequestOrderBO> searchRequestOrders(RequestOrderQuery query) {
        //1. 使用仓储层查询总数
        Long total = demandRepository.getRequestOrderCount(query);
        //判断
        ListRecordTotalBO<RequestOrderBO> listBO=null;
        if (total==0){
            listBO=new ListRecordTotalBO<>(null,0L);
        }else{
            //2. total不是0 可以查询list数据
            List<RequestOrderBO> bos = demandRepository.queryRequestOrders(query);
            //3. bos中元素所有的viewOrderAmount展示给师傅的金额做计算 原价*(100-20)%
            calculateViewAmount(bos);
            listBO=new ListRecordTotalBO<>(bos, total);
        }
        return listBO;
    }
    /**
     * 计算展示给师傅的金额. bos数据中有订单原价 orderAmount 需要和profitScale(定死20)平台分润做计算
     * 得到展示价格viewOrderAmound
     * 假设 orderAdmoun 1000 profitScale 20
     * 1000*(100-20)/100=800
     * 使用如果是int long dubble好说 但是这里属性全部使用BigDecimall 所以不能直接算 需要使用api方法
     */
    private void calculateViewAmount(List<RequestOrderBO> bos) {
        //1. 定死每一个需求单的分润都是20 dubble有精度问题 bigDecimal没有
        BigDecimal profitScale = new BigDecimal("20");
        //2. 循环查询bos 每一个bo都计算展示价格
        if (!CollectionUtils.isEmpty(bos)) {
            for (RequestOrderBO bo : bos) {
                //当前订单原价 假设 1000
                Long orderAmount = bo.getOrderAmount();
                //每个订单的分润 写死20 等于20% 1000*(100-20)/100=800
                BigDecimal workerPercent=
                    new BigDecimal("100")
                        .subtract(profitScale)
                        .divide(new BigDecimal("100"));
                log.info("当前师傅分润是:{}",workerPercent);
                Long viewOrderAmount=new BigDecimal(orderAmount).multiply(workerPercent).longValue();
                //将viewOrderAmount和profitScale两个数字放到bo
                bo.setViewOrderAmount(viewOrderAmount);
                bo.setProfitScale(profitScale);
            }
        }
    }

    @Autowired
    private StringRedisTemplate redisTemplate;
    public Boolean grabOrder(String requestOrderNo) {
        //直接调用仓储层 update request_order set grab_status=1 where request_order_no=#{no} and grab_status=0
        //1. key值
        String lockKey="luban:order:grab:"+requestOrderNo;
        ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
        Boolean tryLock=false;
        try{
            tryLock=opsForValue.setIfAbsent(lockKey,"",10, TimeUnit.SECONDS);
            if (tryLock){
                Integer count=demandRepository.grabOrder(requestOrderNo);
                return count==1;
            }
        }catch (Throwable e){
            log.error("抢单失败",e);
        }finally {
            redisTemplate.delete(lockKey);
        }
        return false;
    }

}
